package com.tencent.iov.cowin.befsale.clue.dao.redis;

import com.software.boot.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author：Robot.wang
 * @date: 2019-06-22
 * @description:
 */
@Slf4j
@Component
//@ConditionalOnProperty(prefix = "comm-config",name = "redis",havingValue = "true")
public class CommRedisDao {

    @Resource(name = "jacksonRedisTemplate")
    RedisTemplate redisTemplate;

    @Resource(name = "stringStringRedisTemplate")
    RedisTemplate<String, String> stringRedisTemplate;

    private static Logger logger = LoggerFactory.getLogger(CommRedisDao.class);

    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    public String getByString(String key) {
        return key == null ? null : stringRedisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public boolean del(String key) throws BusinessException {
        try{
            return redisTemplate.delete(key);
        }catch (Exception e){
            throw new BusinessException();
        }
    }

    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean increment(String key, long delat) {
        try {
            redisTemplate.opsForValue().increment(delat);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public Long increment(String key) {
        try {
            return redisTemplate.opsForValue().increment(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean setCacheSeconds(String key, Object value, long time) {
        try {
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            log.info("setSeconds error, key:{} , value:{}, error:{}", key, value, e);
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean setMs(String key, Object value, long time) {
        try {
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);
            return true;
        } catch (Exception e) {
            return false;
        }
    }






    /**
     * 添加zset对象
     *
     * @param zsetName zset名字
     * @param key      key
     * @param score    分数
     */
    public void zadd(final String zsetName, String key, long score) {
        try {
            redisTemplate.opsForZSet().add(zsetName, key, score);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取zset最小值
     * @param zsetName
     * @return
     */
    public Object zmin(final String zsetName) {
        try {
            if (redisTemplate.opsForZSet().size(zsetName) > 0) {
                Set resultSet = redisTemplate.opsForZSet().range(zsetName, 0, 0);
                if (resultSet.iterator().hasNext()) {
                    return resultSet.iterator().next();
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 从zset 根据key得到 score
     * @param zsetName
     * @param key
     */
    public Double zgetScore(final String zsetName, String key) {
        try {
            if (redisTemplate.opsForZSet().size(zsetName) != null) {
                return redisTemplate.opsForZSet().score(zsetName, key);
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 删除zset对象
     *
     * @param zsetName
     * @param key
     */
    public void zremove(final String zsetName, String key) {
        try {
            if (redisTemplate.opsForZSet().size(zsetName) > 0) {
                redisTemplate.opsForZSet().remove(zsetName, key);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }


    /**
     * 从zset移除
     * @param zsetName
     * @param keyName
     * @throws Exception
     */
    public void removeZset(String zsetName, String keyName) throws Exception{
        try {
            zremove(zsetName, keyName);
        }catch (Exception e){
            logger.info("Redis removeZset Error:"+e.getMessage());
            throw new RuntimeException("Redis Error:"+e.getMessage());
        }
    }


    /**
     * zaddList
     * @param key
     * @param value
     * @return
     */
    public Long lPush(String key, String value){
        return redisTemplate.opsForList().rightPush(key,value);
    }

    /**
     * zGet
     * @param key
     * @return
     */
    public Object lPop(String key){
        return  redisTemplate.opsForList().leftPop(key);
    }

    /**
     * sAdd
     * @param key
     * @return
     */
    public Object sAdd(String key, String value){
        return  redisTemplate.opsForSet().add(key, value);
    }

    /**
     * spop
     * @param key
     * @return
     */
    public Object sPop(String key){
        return  redisTemplate.opsForSet().pop(key);
    }

    /**
     * list的size
     * @param key
     * @return
     */
    public Long lLength(String key){
        return redisTemplate.opsForList().size(key);
    }

    /**
     * 获取list指定范围内元素
     * @param key
     * @param start
     * @param end
     * @return
     */
    public List<Object> lRange(String key, Long start, Long end){
        return redisTemplate.opsForList().range(key,start,end);
    }

    /**
     * 修改list
     * index：要修改的元素的索引
     * value：将要修改的元素改成这个值
     */
    public void lChange(String listName,long index,String value) {
        redisTemplate.opsForList().set(listName, index, value);
    }
    /**
     * 删除list元素
     * value：要删除的元素的值
     * count：删除的元素个数。
     * 当count=0，删除list中所有值为value的元素；
     * 当count>0，从头开始，删除list中值为value的元素，删除的个数为count个
     * 当count<0，从尾开始，删除list中值为value的元素，删除的个数为|count|(count的绝对值)个
     */
    public Long lDelete(String listName,int count,String value) {
        return redisTemplate.opsForList().remove(listName,count,value);
    }

    public void expire(String key, int timeout, TimeUnit timeUnit) {
        redisTemplate.expire(key, timeout, timeUnit);
    }
}
